﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.IdentityModel.Tokens;
using Zhp.Common.Extention;
using Zhp.Common.Helper;
using Zhp.Entity.App;
using Zhp.Model.Common;

namespace Zhp.Api.ActionExtension.Attributes
{
    /// <summary>
    /// 签名校验
    /// </summary>
    public class VerifySignAttribute : BaseActionFilter
    {
        public override async Task OnActionExecuting(ActionExecutingContext context)
        {
            var request = context.HttpContext.Request;

            base.HttpContext = context.HttpContext;

            var appId = request.Headers["appid"].ToString();
            if (string.IsNullOrEmpty(appId))
            {
                context.Result = Error("缺少header:appid");
                return;
            }

            var sign = request.Headers["sign"].ToString();
            if (string.IsNullOrEmpty(sign))
            {
                context.Result = Error("缺少header:sign");
                return;
            }

            var timeStamp = request.Headers["timstamp"].ToString();
            if (string.IsNullOrEmpty(timeStamp))
            {
                context.Result = Error("缺少header:timstamp");
                return;
            }

            var now = DateTimeOffset.FromUnixTimeMilliseconds(Convert.ToInt64(timeStamp)).ToLocalTime();
            var nowTime = DateTime.Now;
            var sc = (nowTime - now).TotalSeconds;
            if (sc > 5)
            {
                context.Result = Error("time请求超时");
                return;
            }

            var appInfo = await AppSecret.SingleAsync(x => x.AppId == appId);
            if (appInfo == null)
            {
                context.Result = Error("header:appId无效");
                return;
            }

            string body = string.Empty;
            if (!request.HasFormContentType)
            {
                body = await request.Body.ReadToString();
            }
            
            string signnew = CreateSign(appId, appInfo.AppSecretKey, timeStamp, body, request.Path.Value + request.QueryString);

            if (sign != signnew)
            {
                context.Result = Error("签名错误！");
            }
        }

        private string CreateSign(string appId, string appSecret, string timeStamp, string body, string path)
        {
            return $"{appId}{timeStamp}{body}{appSecret}{path}".ToMd5String();
        }

        private JsonResult Error(string msg)
        {
            var result = new JsonResult(new ApiResult
            {
                Status = StatusCodes.Status400BadRequest,
                Message = msg,
                Url = base.HttpContext?.Request.Path
            });

            result.StatusCode = StatusCodes.Status400BadRequest;

            return result;
        }
    }

}
